import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import axios from 'axios';
import { AppModule } from '../src/app.module';

describe('Users Module (e2e)', () => {
    let app: INestApplication;
    let baseUrl: string;
    let authToken: string;
    let testUserId: number;

    beforeAll(async () => {
        const moduleFixture: TestingModule = await Test.createTestingModule({
            imports: [AppModule],
        }).compile();

        app = moduleFixture.createNestApplication();
        await app.init();

        baseUrl = 'http://localhost:3000';

        // 尝试获取认证令牌（在实际测试中，你可能需要先创建一个测试用户）
        try {
            const authResponse = await axios.post(`${baseUrl}/api/v1/auth/wallet-login`, {
                walletAddress: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
                message: 'Test authentication for e2e tests',
                signature: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
                fullName: 'Test User'
            });

            if (authResponse.status === 200) {
                authToken = authResponse.data.access_token;
                testUserId = authResponse.data.user.id || 1;
                console.log('✅ Authentication successful for testing');
            }
        } catch (error) {
            console.log('⚠️ Authentication failed, some tests may be skipped:', error.response?.data || error.message);
        }
    });

    afterAll(async () => {
        await app.close();
    });

    describe('GET /api/v1/users/me', () => {
        it('should get current user information when authenticated', async () => {
            if (!authToken) {
                console.log('⏭️ Skipping test - no auth token available');
                return;
            }

            try {
                const response = await axios.get(`${baseUrl}/api/v1/users/me`, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`,
                    },
                });

                expect(response.status).toBe(200);
                expect(response.data).toHaveProperty('success', true);
                expect(response.data).toHaveProperty('data');
                expect(response.data.data).toHaveProperty('walletAddress');
                expect(response.data.data).toHaveProperty('fullName');

                console.log('✅ Get current user successful:', response.data);
            } catch (error) {
                console.log('❌ Get current user failed:', error.response?.data || error.message);
                expect(error.response?.status).toBe(401); // 期望是401未授权
            }
        });

        it('should reject request without authentication', async () => {
            try {
                await axios.get(`${baseUrl}/api/v1/users/me`);
                fail('Should have thrown an error');
            } catch (error) {
                expect(error.response?.status).toBe(401); // 期望是401未授权
                console.log('✅ Unauthenticated request correctly rejected');
            }
        });
    });

    describe('PATCH /api/v1/users/me', () => {
        it('should update current user information when authenticated', async () => {
            if (!authToken) {
                console.log('⏭️ Skipping test - no auth token available');
                return;
            }

            const updateData = {
                fullName: 'Updated Test User',
                email: 'updated@test.com'
            };

            try {
                const response = await axios.patch(`${baseUrl}/api/v1/users/me`, updateData, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`,
                        'Content-Type': 'application/json',
                    },
                });

                expect(response.status).toBe(200);
                expect(response.data).toHaveProperty('success', true);
                expect(response.data).toHaveProperty('data');
                expect(response.data.data.fullName).toBe(updateData.fullName);
                expect(response.data.data.email).toBe(updateData.email);

                console.log('✅ Update current user successful:', response.data);
            } catch (error) {
                console.log('❌ Update current user failed:', error.response?.data || error.message);
                expect(error.response?.status).toBe(401); // 期望是401未授权
            }
        });

        it('should reject update request without authentication', async () => {
            const updateData = {
                fullName: 'Unauthorized Update'
            };

            try {
                await axios.patch(`${baseUrl}/api/v1/users/me`, updateData, {
                    headers: {
                        'Content-Type': 'application/json',
                    },
                });
                fail('Should have thrown an error');
            } catch (error) {
                expect(error.response?.status).toBe(401); // 期望是401未授权
                console.log('✅ Unauthenticated update request correctly rejected');
            }
        });

        it('should validate update data format', async () => {
            if (!authToken) {
                console.log('⏭️ Skipping test - no auth token available');
                return;
            }

            const invalidData = {
                fullName: '', // 空名称应该被拒绝
                email: 'invalid-email' // 无效邮箱格式
            };

            try {
                await axios.patch(`${baseUrl}/api/v1/users/me`, invalidData, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`,
                        'Content-Type': 'application/json',
                    },
                });
                fail('Should have thrown an error');
            } catch (error) {
                expect(error.response?.status).toBe(400); // 期望是400错误请求
                console.log('✅ Invalid update data correctly rejected');
            }
        });
    });

    describe('GET /api/v1/users/:id', () => {
        it('should get user by ID when authenticated', async () => {
            if (!authToken) {
                console.log('⏭️ Skipping test - no auth token available');
                return;
            }

            try {
                const response = await axios.get(`${baseUrl}/api/v1/users/${testUserId}`, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`,
                    },
                });

                expect(response.status).toBe(200);
                expect(response.data).toHaveProperty('success', true);
                expect(response.data).toHaveProperty('data');
                expect(response.data.data).toHaveProperty('id', testUserId);

                console.log('✅ Get user by ID successful:', response.data);
            } catch (error) {
                console.log('❌ Get user by ID failed:', error.response?.data || error.message);
                expect(error.response?.status).toBe(401); // 期望是401未授权
            }
        });

        it('should reject request without authentication', async () => {
            try {
                await axios.get(`${baseUrl}/api/v1/users/1`);
                fail('Should have thrown an error');
            } catch (error) {
                expect(error.response?.status).toBe(401); // 期望是401未授权
                console.log('✅ Unauthenticated get user by ID request correctly rejected');
            }
        });

        it('should handle non-existent user ID', async () => {
            if (!authToken) {
                console.log('⏭️ Skipping test - no auth token available');
                return;
            }

            try {
                await axios.get(`${baseUrl}/api/v1/users/99999`, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`,
                    },
                });
                fail('Should have thrown an error');
            } catch (error) {
                expect(error.response?.status).toBe(404); // 期望是404未找到
                console.log('✅ Non-existent user ID correctly handled');
            }
        });
    });

    describe('GET /api/v1/users/wallet/:address', () => {
        it('should get user by wallet address when authenticated', async () => {
            if (!authToken) {
                console.log('⏭️ Skipping test - no auth token available');
                return;
            }

            const walletAddress = '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6';

            try {
                const response = await axios.get(`${baseUrl}/api/v1/users/wallet/${walletAddress}`, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`,
                    },
                });

                expect(response.status).toBe(200);
                expect(response.data).toHaveProperty('success', true);
                expect(response.data).toHaveProperty('data');
                expect(response.data.data).toHaveProperty('walletAddress', walletAddress);

                console.log('✅ Get user by wallet address successful:', response.data);
            } catch (error) {
                console.log('❌ Get user by wallet address failed:', error.response?.data || error.message);
                expect(error.response?.status).toBe(401); // 期望是401未授权
            }
        });

        it('should reject request without authentication', async () => {
            try {
                await axios.get(`${baseUrl}/api/v1/users/wallet/0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6`);
                fail('Should have thrown an error');
            } catch (error) {
                expect(error.response?.status).toBe(401); // 期望是401未授权
                console.log('✅ Unauthenticated get user by wallet address request correctly rejected');
            }
        });

        it('should handle non-existent wallet address', async () => {
            if (!authToken) {
                console.log('⏭️ Skipping test - no auth token available');
                return;
            }

            const nonExistentAddress = '0x0000000000000000000000000000000000000000';

            try {
                await axios.get(`${baseUrl}/api/v1/users/wallet/${nonExistentAddress}`, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`,
                    },
                });
                fail('Should have thrown an error');
            } catch (error) {
                expect(error.response?.status).toBe(404); // 期望是404未找到
                console.log('✅ Non-existent wallet address correctly handled');
            }
        });
    });
});
